package com.tbit.uqbike.compalint.service;

import com.alipay.v3.ApiClient;
import com.alipay.v3.ApiException;
import com.alipay.v3.Configuration;
import com.alipay.v3.api.AlipayMerchantTradecomplainApi;
import com.alipay.v3.api.AlipayMerchantTradecomplainFeedbackApi;
import com.alipay.v3.api.AlipayMerchantTradecomplainReplyApi;
import com.alipay.v3.model.*;
import com.alipay.v3.util.model.AlipayConfig;
import com.tbit.common.config.OssDefaultConfig;
import com.tbit.uqbike.compalint.enums.ComplaintStatusEnum;
import com.tbit.uqbike.compalint.enums.PlatformEnum;
import com.tbit.uqbike.compalint.param.*;
import com.tbit.uqbike.compalint.service.base.AbstractComplaintService;
import com.tbit.uqbike.compalint.table.ComplaintDO;
import com.tbit.uqbike.compalint.table.ComplaintHistoryDO;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.Recharge;
import com.tbit.uqbike.object.pojo.ZfbPayConfig;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.service.business.RechargeService;
import com.tbit.uqbike.webmanager.dao.core.ZfbPayConfigDao;
import com.tbit.uqbike.compalint.mapper.ComplaintHistoryMapper;
import com.tbit.uqbike.compalint.mapper.ComplaintMapper;
import com.tbit.uqbike.webmanager.util.HttpClientUtils;
import com.tbit.uqbike.webmanager.util.MD5Util;
import com.tbit.uqbike.webmanager.util.UserContextUtil;
import com.tbit.uqbike.webmanager.util.aliyun.OssFileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 支付宝客诉api
 *
 * @author <a href="mailto:zhang.zhiliang@tbit.com.cn">Zhang ZhiLiang</a>
 * @version 1.0
 * @see <a href="http://adsl1.tbit.com.cn:21490/pages/viewpage.action?pageId=82182491">订单号规范</a>
 * @since 2025/2/14
 */
@Slf4j
@Service(value = "ZFBComplaintService")
public class ZFBComplaintService extends AbstractComplaintService {

    private final ZfbPayConfigDao zfbPayConfigDao;
    private final ApiClient defaultClient;
    private final RechargeService rechargeService;

    @Autowired
    public ZFBComplaintService(ComplaintMapper complaintMapper, ComplaintHistoryMapper complaintHistoryMapper,
                               OssDefaultConfig ossDefaultConfig, ZfbPayConfigDao zfbPayConfigDao, RechargeService rechargeService) {
        super(complaintMapper, complaintHistoryMapper, ossDefaultConfig);
        this.zfbPayConfigDao = zfbPayConfigDao;
        this.defaultClient = Configuration.getDefaultApiClient();
        this.rechargeService = rechargeService;
    }

    @Override
    public Boolean responseApi(ComplaintResponseParam param) {
        if (Objects.isNull(init(param.getBrandId()))){
            throw new BaseException(String.format("%s支付宝品牌配置初始化失败,回复失败", param.getBrandId()));
        }
        AlipayMerchantTradecomplainReplyApi api = new AlipayMerchantTradecomplainReplyApi();
        AlipayMerchantTradecomplainReplySubmitModel data = getAlipayMerchantTradecomplainReplySubmitModel(param.getComplaintId(),param.getContent());
        try {
            Object response = api.submit(data);
            return true;
        } catch (ApiException e) {
            AlipayMerchantTradecomplainReplySubmitDefaultResponse errorObject = (AlipayMerchantTradecomplainReplySubmitDefaultResponse) e.getErrorObject();
            log.error("调用失败:" + errorObject);
            return false;
        }
    }

    @Override
    public ComplaintStatusEnum getDetailApi(ComplaintVerifyParam param) {
        if (Objects.isNull(init(param.getBrandId()))){
            log.warn(String.format("%s支付宝品牌配置初始化失败,状态获取失败", param.getBrandId()));
            return null;
        }
        AlipayMerchantTradecomplainApi api = new AlipayMerchantTradecomplainApi();
        try {
            AlipayMerchantTradecomplainQueryResponseModel response = api.query(param.getComplaintId());
            return ComplaintStatusEnum.getComplaintEnumByZFB(response.getStatus());
        } catch (ApiException e) {
            AlipayMerchantTradecomplainQueryDefaultResponse errorObject = (AlipayMerchantTradecomplainQueryDefaultResponse) e.getErrorObject();
            log.error("支付宝获取详情调用失败:" + errorObject);
            return null;
        }
    }

    @Override
    public List<ComplaintHistoryDO> getHistoryDetailApi(ComplaintHistoryParam param) {
        if (Objects.isNull(init(param.getBrandId()))){
            log.warn(String.format("%s支付宝品牌配置初始化失败,拉取协商历史失败", param.getBrandId()));
            return new ArrayList<ComplaintHistoryDO>();
        }
        AlipayMerchantTradecomplainApi api = new AlipayMerchantTradecomplainApi();
        try {
            AlipayMerchantTradecomplainQueryResponseModel response = api.query(param.getComplaintId());
            List<ReplyRecordResponse> replyDetailInfos = response.getReplyDetailInfos();
            return parseToComplaintHistoryDOList(param.getComplaintId(),replyDetailInfos);
        } catch (ApiException e) {
            AlipayMerchantTradecomplainQueryDefaultResponse errorObject = (AlipayMerchantTradecomplainQueryDefaultResponse) e.getErrorObject();
            log.error("支付宝获取详情调用失败:" + errorObject);
            return new ArrayList<ComplaintHistoryDO>();
        }
    }

    @Override
    public Boolean completeApi(ComplaintCompleteParam param) {
        if (Objects.isNull(init(param.getBrandId()))){
            log.warn(String.format("%s支付宝品牌配置初始化失败,反馈客诉完成失败", param.getBrandId()));
            return false;
        }
        AlipayMerchantTradecomplainFeedbackApi api = new AlipayMerchantTradecomplainFeedbackApi();
        LoginInfo loginInfo = (LoginInfo) UserContextUtil.get(UserContextUtil.USER_KEY);
        AlipayMerchantTradecomplainFeedbackSubmitModel data = getAlipayMerchantTradecomplainFeedbackSubmitModel("04","已处理完成",param.getComplaintId(),loginInfo.getName());
        try {
            Object response = api.submit(data);
            return true;
        } catch (ApiException e) {
            AlipayMerchantTradecomplainFeedbackSubmitDefaultResponse errorObject = (AlipayMerchantTradecomplainFeedbackSubmitDefaultResponse) e.getErrorObject();
            log.error("调用失败:" + errorObject);
            return false;
        }
    }

    @Override
    public List<ComplaintDO> pullComplaintApi(ComplaintPullParam param) {
        String appId = init(param.getBrandId());
        if (Objects.isNull(appId)){
            log.warn(String.format("%s支付宝品牌配置初始化失败,拉取客诉失败", param.getBrandId()));
            return new ArrayList<ComplaintDO>();
        }
        AlipayMerchantTradecomplainApi api = new AlipayMerchantTradecomplainApi();
        AlipayMerchantTradecomplainBatchqueryModel data = getAlipayMerchantTradecomplainBatchqueryModel(appId,param);
        try {
            AlipayMerchantTradecomplainBatchqueryResponseModel response = api.batchquery(data);
            List<TradeComplainQueryResponse> tradeComplainInfos = response.getTradeComplainInfos();
            return parseToComplaintDOList(param.getBrandId(),tradeComplainInfos);
        } catch (ApiException e) {
            AlipayMerchantTradecomplainBatchqueryDefaultResponse errorObject = (AlipayMerchantTradecomplainBatchqueryDefaultResponse) e.getErrorObject();
            log.error("调用失败:" + errorObject);
            return new ArrayList<ComplaintDO>();
        }
    }

    /**
     * 初始化alipay
     * @param appid 应用id
     * @param privateKey 应用私钥
     * @param alipayPublicKey 支付宝公钥
     * @return
     */
    private AlipayConfig getAlipayConfig(String appid,String privateKey,String alipayPublicKey){
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipay.com");
        alipayConfig.setAppId(appid);
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        return alipayConfig;
    }

    /**
     * 初始化阿里客户端配置
     * @param brandId 品牌名
     * @return 商户名 appId
     */
    private String init(Integer brandId){
        // 查询支付宝配置
        ZfbPayConfig zfbPayConfig = zfbPayConfigDao.getByAccountId(brandId, 1);
        if (Objects.isNull(zfbPayConfig)){
            return null;
        }
        AlipayConfig alipayConfig = getAlipayConfig(zfbPayConfig.getPartner(),zfbPayConfig.getPriKey(), zfbPayConfig.getPubKey());
        try {
            defaultClient.setAlipayConfig(alipayConfig);
            return zfbPayConfig.getPartner();
        } catch (ApiException e) {
            log.error("初始化阿里配置失败",e);
            return null;
        }
    }

    /**
     * 回复客诉参数
     * @return
     */
    private AlipayMerchantTradecomplainReplySubmitModel getAlipayMerchantTradecomplainReplySubmitModel(String complainEventId,String replyContent) {
        AlipayMerchantTradecomplainReplySubmitModel data = new AlipayMerchantTradecomplainReplySubmitModel();
//        data.setReplyImages("ySYHS5CtTCmag14Wk8jeNAAAACMAAQEW,ySYHS5CtTCmag14Wk8jeNAAAACMAAQAX");
        data.setComplainEventId(complainEventId);
        data.setReplyContent(replyContent);
        return data;
    }

    /**
     * 解析支付宝客诉列表
     * @param brandId 品牌名
     * @param tradeComplainInfos 支付宝api返回的客诉列表
     * @return 客诉数据库实体列表
     */
    private List<ComplaintDO> parseToComplaintDOList(Integer brandId, List<TradeComplainQueryResponse> tradeComplainInfos){
        List<ComplaintDO> complaintDOList = new ArrayList<>();
        if (Objects.isNull(tradeComplainInfos) || tradeComplainInfos.isEmpty()){
            log.warn("品牌{}支付宝拉取客诉列表为空",brandId);
            return complaintDOList;
        }
        for (TradeComplainQueryResponse tradeComplainInfo : tradeComplainInfos) {
            LocalDateTime complaintTime = Objects.isNull(tradeComplainInfo.getGmtCreate()) ? LocalDateTime.now() : LocalDateTime.parse(tradeComplainInfo.getGmtCreate(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String orderNO = tradeComplainInfo.getMerchantOrderNo();
            Recharge recharge = rechargeService.getRechargeByOrderNO(orderNO);
            int money = Objects.nonNull(recharge) ? recharge.getMoney().intValue() : -1 ;
            String complaintId = tradeComplainInfo.getComplainEventId();
            String picture = getZFBPicture(complaintId,tradeComplainInfo.getImages());
            complaintDOList.add(
                    new ComplaintDO().setBrandId(brandId).setComplaintId(complaintId)
                            .setComplaintTime(complaintTime).setPlatform(PlatformEnum.ZFB.getCode())
                            .setOrderMoney(money).setDescription(tradeComplainInfo.getContent())
                            .setPicture(picture).setPhone(tradeComplainInfo.getPhoneNo())
                            .setOrderNO(orderNO).setStatus(ComplaintStatusEnum.NEW.getCode())
            );
        }
        return complaintDOList;
    }

    /**
     * 处理支付宝图片
     * 1. 根据返回的url下载图片
     * 2. 上传至oss
     * 3. 获取oss下载地址 拼接返回
     * @param images 支付宝返回的图片url
     * @param complaintId 投诉单号
     * @return ossUrl 拼接的字符串
     */
    private String getZFBPicture(String complaintId, List<String> images) {
        if (Objects.isNull(images) || images.isEmpty()){
            return null;
        }
        StringBuilder pictureBuilder = new StringBuilder();
        for (String image : images) {
            InputStream inputStream = HttpClientUtils.httpGetFile(image, null);
            try {
                String ossUrl = OssFileUtils.uploadByAliYun(inputStream, getOssConfig(), String.format("complaint/ZFB-picture-%s",UUID.randomUUID()), "image/jpeg", OssFileUtils.IMAGE);
                pictureBuilder.append(ossUrl).append(";");
            } catch (Exception e) {
                log.error("投诉单号{}图片处理失败",complaintId,e);
            }
        }
        if (pictureBuilder.length() > 0){
            pictureBuilder.delete(pictureBuilder.length()-1, pictureBuilder.length());
        }
        return pictureBuilder.toString();
    }

    /**
     * 拉取客诉列表参数
     * @return
     */
    private AlipayMerchantTradecomplainBatchqueryModel getAlipayMerchantTradecomplainBatchqueryModel(String appId, ComplaintPullParam param) {
        AlipayMerchantTradecomplainBatchqueryModel data = new AlipayMerchantTradecomplainBatchqueryModel();
        data.setBeginTime(param.getStartTime());
        // 根据offset 推演 pageNum ， 当页大小为 20 页 时 ， 当前偏移为 25 ， 则页码为 2 ， 拉取的数据会有 5条重复 ， 入库时做了清洗
        int pageNum = param.getOffset()/param.getLimit() + 1;
        data.setPageNum(pageNum);
        data.setPageSize(param.getLimit());
        List<TargetInfo> targetInfos = new ArrayList<TargetInfo>();
        TargetInfo targetInfos0 = new TargetInfo();
        targetInfos0.setTargetId(appId);
        targetInfos0.setTargetType("APPID");
        targetInfos.add(targetInfos0);
        data.setTargetInfos(targetInfos);
        data.setEndTime(param.getEndTime());
//        data.setStatus("MERCHANT_PROCESSING");
        return data;
    }

    /**
     * 处理客诉参数构造
     * @return
     */
    private AlipayMerchantTradecomplainFeedbackSubmitModel getAlipayMerchantTradecomplainFeedbackSubmitModel(String feedbackCode, String feedbackContent, String complaintEventId, String operator) {
        AlipayMerchantTradecomplainFeedbackSubmitModel data = new AlipayMerchantTradecomplainFeedbackSubmitModel();
        data.setFeedbackCode(feedbackCode);
        data.setFeedbackContent(feedbackContent);
        data.setComplainEventId(complaintEventId);
//        data.setFeedbackImages("wAe1XmjGS8mBSV0FFklAUgAAACMAAQED,A*C5jFT7v7SIMAAAAAAAAAAAAADpp1AQ");
        data.setOperator(operator);
        return data;
    }

    private List<ComplaintHistoryDO> parseToComplaintHistoryDOList(String complaintId,List<ReplyRecordResponse> replyDetailInfos){
        List<ComplaintHistoryDO> complaintHistoryDOList = new ArrayList<>();
        if (Objects.isNull(replyDetailInfos) || replyDetailInfos.isEmpty()){
            log.warn("投诉单号{}支付宝客诉协商历史为空",complaintId);
            return complaintHistoryDOList;
        }
        for (ReplyRecordResponse replyDetailInfo : replyDetailInfos) {
            String sender = !Objects.equals(replyDetailInfo.getReplierRole(),"USER") ? SYSTEM : COMPLAINANT;
            complaintHistoryDOList.add(
                    new ComplaintHistoryDO().setComplaintId(complaintId)
                            .setUuid(MD5Util.MD5Encode(replyDetailInfo.toString(), "UTF-8"))
                            .setSender(sender).setAdminFlag(!Objects.equals(replyDetailInfo.getReplierRole(),"USER"))
                            .setContent(replyDetailInfo.getContent())
                            .setPicture(getZFBPicture(complaintId,replyDetailInfo.getImages()))
                            .setSendTime(LocalDateTime.parse(replyDetailInfo.getGmtCreate(),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
            );
        }
        return complaintHistoryDOList;
    }

}
